<html><head><meta charset="utf-8"/><title>操作DOM</title></head><body><h1>操作DOM</h1><div class="x-wiki-content x-main-content">
 <p>
  jQuery的选择器很强大，用起来又简单又灵活，但是搞了这么久，我拿到了jQuery对象，到底要干什么？
 </p>
 <p>
  答案当然是操作对应的DOM节点啦！
 </p>
 <p>
  回顾一下修改DOM的CSS、文本、设置HTML有多么麻烦，而且有的浏览器只有innerHTML，有的浏览器支持innerText，有了jQuery对象，不需要考虑浏览器差异了，全部统一操作！
 </p>
 <h3>
  修改Text和HTML
 </h3>
 <p>
  jQuery对象的
  <code>
   text()
  </code>
  和
  <code>
   html()
  </code>
  方法分别获取节点的文本和原始HTML文本，例如，如下的HTML结构：
 </p>
 <pre><code>&lt;!-- HTML结构 --&gt;
&lt;ul id="test-ul"&gt;
    &lt;li class="js"&gt;JavaScript&lt;/li&gt;
    &lt;li name="book"&gt;Java &amp;amp; JavaScript&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
 <p>
  分别获取文本和HTML：
 </p>
 <pre><code>$('#test-ul li[name=book]').text(); // 'Java &amp; JavaScript'
$('#test-ul li[name=book]').html(); // 'Java &amp;amp; JavaScript'
</code></pre>
 <p>
  如何设置文本或HTML？jQuery的API设计非常巧妙：无参数调用
  <code>
   text()
  </code>
  是获取文本，传入参数就变成设置文本，HTML也是类似操作，自己动手试试：
 </p>
 <pre><code class="language-x-javascript">'use strict';
var j1 = $('#test-ul li.js');
var j2 = $('#test-ul li[name=book]');
----
j1.html('&lt;span style="color: red"&gt;JavaScript&lt;/span&gt;');
j2.text('JavaScript &amp; ECMAScript');
</code></pre>
 <ul id="test-ul">
  <li class="js">
   JavaScript
  </li>
  <li name="book">
   Java &amp; JavaScript
  </li>
 </ul>
 <p>
  一个jQuery对象可以包含0个或任意个DOM对象，它的方法实际上会作用在对应的每个DOM节点上。在上面的例子中试试：
 </p>
 <pre><code>$('#test-ul li').text('JS'); // 是不是两个节点都变成了JS？
</code></pre>
 <p>
  所以jQuery对象的另一个好处是我们可以执行一个操作，作用在对应的一组DOM节点上。即使选择器没有返回任何DOM节点，调用jQuery对象的方法仍然不会报错：
 </p>
 <pre><code>// 如果不存在id为not-exist的节点：
$('#not-exist').text('Hello'); // 代码不报错，没有节点被设置为'Hello'
</code></pre>
 <p>
  这意味着jQuery帮你免去了许多
  <code>
   if
  </code>
  语句。
 </p>
 <h3>
  修改CSS
 </h3>
 <p>
  jQuery对象有“批量操作”的特点，这用于修改CSS实在是太方便了。考虑下面的HTML结构：
 </p>
 <pre><code>&lt;!-- HTML结构 --&gt;
&lt;ul id="test-css"&gt;
    &lt;li class="lang dy"&gt;&lt;span&gt;JavaScript&lt;/span&gt;&lt;/li&gt;
    &lt;li class="lang"&gt;&lt;span&gt;Java&lt;/span&gt;&lt;/li&gt;
    &lt;li class="lang dy"&gt;&lt;span&gt;Python&lt;/span&gt;&lt;/li&gt;
    &lt;li class="lang"&gt;&lt;span&gt;Swift&lt;/span&gt;&lt;/li&gt;
    &lt;li class="lang dy"&gt;&lt;span&gt;Scheme&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
 <p>
  要高亮显示动态语言，调用jQuery对象的
  <code>
   css('name', 'value')
  </code>
  方法，我们用一行语句实现：
 </p>
 <pre><code class="language-x-javascript">'use strict';
----
$('#test-css li.dy&gt;span').css('background-color', '#ffd351').css('color', 'red');
</code></pre>
 <ul id="test-css">
  <li class="lang dy">
   <span>
    JavaScript
   </span>
  </li>
  <li class="lang">
   <span>
    Java
   </span>
  </li>
  <li class="lang dy">
   <span>
    Python
   </span>
  </li>
  <li class="lang">
   <span>
    Swift
   </span>
  </li>
  <li class="lang dy">
   <span>
    Scheme
   </span>
  </li>
 </ul>
 <p>
  <em>
   注意
  </em>
  ，jQuery对象的所有方法都返回一个jQuery对象（可能是新的也可能是自身），这样我们可以进行链式调用，非常方便。
 </p>
 <p>
  jQuery对象的
  <code>
   css()
  </code>
  方法可以这么用：
 </p>
 <pre><code>var div = $('#test-div');
div.css('color'); // '#000033', 获取CSS属性
div.css('color', '#336699'); // 设置CSS属性
div.css('color', ''); // 清除CSS属性
</code></pre>
 <p>
  为了和JavaScript保持一致，CSS属性可以用
  <code>
   'background-color'
  </code>
  和
  <code>
   'backgroundColor'
  </code>
  两种格式。
 </p>
 <p>
  <code>
   css()
  </code>
  方法将作用于DOM节点的
  <code>
   style
  </code>
  属性，具有最高优先级。如果要修改
  <code>
   class
  </code>
  属性，可以用jQuery提供的下列方法：
 </p>
 <pre><code>var div = $('#test-div');
div.hasClass('highlight'); // false， class是否包含highlight
div.addClass('highlight'); // 添加highlight这个class
div.removeClass('highlight'); // 删除highlight这个class
</code></pre>
 <p>
  练习：分别用
  <code>
   css()
  </code>
  方法和
  <code>
   addClass()
  </code>
  方法高亮显示JavaScript：
 </p>
 <pre><code>&lt;!-- HTML结构 --&gt;
&lt;style&gt;
.highlight {
    color: #dd1144;
    background-color: #ffd351;
}
&lt;/style&gt;

&lt;div id="test-highlight-css"&gt;
    &lt;ul&gt;
        &lt;li class="py"&gt;&lt;span&gt;Python&lt;/span&gt;&lt;/li&gt;
        &lt;li class="js"&gt;&lt;span&gt;JavaScript&lt;/span&gt;&lt;/li&gt;
        &lt;li class="sw"&gt;&lt;span&gt;Swift&lt;/span&gt;&lt;/li&gt;
        &lt;li class="hk"&gt;&lt;span&gt;Haskell&lt;/span&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;
</code></pre>
 <pre><code class="language-x-javascript">'use strict';
----
var div = $('#test-highlight-css');
// TODO:
</code></pre>
 <style>
  .highlight {
    color: #dd1144;
    background-color: #ffd351;
}
 </style>
 <div id="test-highlight-css">
  <ul>
   <li class="py">
    <span>
     Python
    </span>
   </li>
   <li class="js">
    <span>
     JavaScript
    </span>
   </li>
   <li class="sw">
    <span>
     Swift
    </span>
   </li>
   <li class="hk">
    <span>
     Haskell
    </span>
   </li>
  </ul>
 </div>
 <h3>
  显示和隐藏DOM
 </h3>
 <p>
  要隐藏一个DOM，我们可以设置CSS的
  <code>
   display
  </code>
  属性为
  <code>
   none
  </code>
  ，利用
  <code>
   css()
  </code>
  方法就可以实现。不过，要显示这个DOM就需要恢复原有的
  <code>
   display
  </code>
  属性，这就得先记下来原有的
  <code>
   display
  </code>
  属性到底是
  <code>
   block
  </code>
  还是
  <code>
   inline
  </code>
  还是别的值。
 </p>
 <p>
  考虑到显示和隐藏DOM元素使用非常普遍，jQuery直接提供
  <code>
   show()
  </code>
  和
  <code>
   hide()
  </code>
  方法，我们不用关心它是如何修改
  <code>
   display
  </code>
  属性的，总之它能正常工作：
 </p>
 <pre><code>var a = $('a[target=_blank]');
a.hide(); // 隐藏
a.show(); // 显示
</code></pre>
 <p>
  <em>
   注意
  </em>
  ，隐藏DOM节点并未改变DOM树的结构，它只影响DOM节点的显示。这和删除DOM节点是不同的。
 </p>
 <h3>
  获取DOM信息
 </h3>
 <p>
  利用jQuery对象的若干方法，我们直接可以获取DOM的高宽等信息，而无需针对不同浏览器编写特定代码：
 </p>
 <pre><code>// 浏览器可视窗口大小:
$(window).width(); // 800
$(window).height(); // 600

// HTML文档大小:
$(document).width(); // 800
$(document).height(); // 3500

// 某个div的大小:
var div = $('#test-div');
div.width(); // 600
div.height(); // 300
div.width(400); // 设置CSS属性 width: 400px，是否生效要看CSS是否有效
div.height('200px'); // 设置CSS属性 height: 200px，是否生效要看CSS是否有效
</code></pre>
 <p>
  <code>
   attr()
  </code>
  和
  <code>
   removeAttr()
  </code>
  方法用于操作DOM节点的属性：
 </p>
 <pre><code>// &lt;div id="test-div" name="Test" start="1"&gt;...&lt;/div&gt;
var div = $('#test-div');
div.attr('data'); // undefined, 属性不存在
div.attr('name'); // 'Test'
div.attr('name', 'Hello'); // div的name属性变为'Hello'
div.removeAttr('name'); // 删除name属性
div.attr('name'); // undefined
</code></pre>
 <p>
  <code>
   prop()
  </code>
  方法和
  <code>
   attr()
  </code>
  类似，但是HTML5规定有一种属性在DOM节点中可以没有值，只有出现与不出现两种，例如：
 </p>
 <pre><code>&lt;input id="test-radio" type="radio" name="test" checked value="1"&gt;
</code></pre>
 <p>
  等价于：
 </p>
 <pre><code>&lt;input id="test-radio" type="radio" name="test" checked="checked" value="1"&gt;
</code></pre>
 <p>
  <code>
   attr()
  </code>
  和
  <code>
   prop()
  </code>
  对于属性
  <code>
   checked
  </code>
  处理有所不同：
 </p>
 <pre><code>var radio = $('#test-radio');
radio.attr('checked'); // 'checked'
radio.prop('checked'); // true
</code></pre>
 <p>
  <code>
   prop()
  </code>
  返回值更合理一些。不过，用
  <code>
   is()
  </code>
  方法判断更好：
 </p>
 <pre><code>var radio = $('#test-radio');
radio.is(':checked'); // true
</code></pre>
 <p>
  类似的属性还有
  <code>
   selected
  </code>
  ，处理时最好用
  <code>
   is(':selected')
  </code>
  。
 </p>
 <h3>
  操作表单
 </h3>
 <p>
  对于表单元素，jQuery对象统一提供
  <code>
   val()
  </code>
  方法获取和设置对应的
  <code>
   value
  </code>
  属性：
 </p>
 <pre><code>/*
    &lt;input id="test-input" name="email" value=""&gt;
    &lt;select id="test-select" name="city"&gt;
        &lt;option value="BJ" selected&gt;Beijing&lt;/option&gt;
        &lt;option value="SH"&gt;Shanghai&lt;/option&gt;
        &lt;option value="SZ"&gt;Shenzhen&lt;/option&gt;
    &lt;/select&gt;
    &lt;textarea id="test-textarea"&gt;Hello&lt;/textarea&gt;
*/
var
    input = $('#test-input'),
    select = $('#test-select'),
    textarea = $('#test-textarea');

input.val(); // 'test'
input.val('abc@example.com'); // 文本框的内容已变为abc@example.com

select.val(); // 'BJ'
select.val('SH'); // 选择框已变为Shanghai

textarea.val(); // 'Hello'
textarea.val('Hi'); // 文本区域已更新为'Hi'
</code></pre>
 <p>
  可见，一个
  <code>
   val()
  </code>
  就统一了各种输入框的取值和赋值的问题。
 </p>
</div>
</body></html>